#ifndef GAMEENGINE_GRAPHICS_MESHES_TRGL_MESH_CREATOR_H
#define GAMEENGINE_GRAPHICS_MESHES_TRGL_MESH_CREATOR_H

#include <GameEngine/Graphics/graphics_settings.h>

#include <GameEngine/Graphics/Meshes/mesh_creator.h>
#include <GameEngine/Graphics/Meshes/trgl_mesh_subgroup.h>


#ifdef GAMEENGINE_NAMESPACES
namespace GameEngine {
#endif

//=================================================================================

//! Creator of a triangulated surface mesh
/*!
 *  This class provides an interface to build a triangulated surface mesh. Its main goal is to
 *  automatically triangulate non-simplicial polygons. This triangulation relies on the assumption
 *  that polygons are convex, which may be a strong limitation; with concave polygons, the
 *  triangulation will produce inconsistent surfaces.
 *
 *  The first action to take when using a creator is to prepare the mesh using the prepare_mesh_creation()
 *  function.<br>
 *  Triangles are then generated in four steps: (i) add all the vertex coordinates of the mesh, (ii) declare
 *  the creation of a new polygon, (iii) add the vertex indexes in the correct order - the creator will
 *  automatically organize them into triangles - and (iv) declare the end of a polygon.<br>
 *  Finally, the last action to take is to close the mesh using the finish_mesh_creation() function.
 *
 *  For instance, let's assume one wants the create a unitary quad. The corresponding code would then be:
 *  @code
 *  TrglMesh mesh = ...;
 *  TrglMeshCreator creator(mesh);
 *  
 *  // Prepare the mesh creation
 *  creator.prepare_mesh_creation();
 *  
 *  // Add the vertices
 *  creator.add_vertex( Point3d<float>(0,0,0) );
 *  creator.add_vertex( Point3d<float>(1,0,0) );
 *  creator.add_vertex( Point3d<float>(1,1,0) );
 *  creator.add_vertex( Point3d<float>(0,1,0) );
 *  
 *  // Create a polygon with the quad
 *  creator.begin_polygon();
 *  creator.add_vertex_index(0);
 *  creator.add_vertex_index(1);
 *  creator.add_vertex_index(2);
 *  creator.add_vertex_index(3);
 *  creator.end_polygon();
 *  
 *  // Finish the mesh creation
 *  creator.finish_mesh_creation();
 *  @endcode
 */
class _Graphics_decl TrglMeshCreator : public MeshCreator {

public:
	TrglMeshCreator(TrglMesh& mesh);
	virtual ~TrglMeshCreator();

	virtual bool prepare_mesh_creation();
	virtual bool finish_mesh_creation();

	virtual bool add_vertex(const Point3d<float>& vertex);
	virtual bool add_normal(const Vector3d<float>& normal);
	virtual bool add_texture_coordinate(const TextureCoordinate2d& coord);

	bool set_group_name(const GEString& name);
	bool reset_subgroup();

	virtual bool begin_polygon();
	virtual bool end_polygon();

	virtual bool begin_line();
	virtual bool end_line();

	virtual bool add_vertex_index(SurfaceMesh::VertexIndex index,
		SurfaceMesh::NormalIndex nindex = -1, SurfaceMesh::TextureCoordinateIndex cindex = -1);

	Material& subgroup_material();
	bool& subgroup_use_transparency();

protected:
	//! The mesh associated to the creator
	TrglMesh& mesh_;

	//! The current mode of the mesh creator
	Mode mode_;
	//! The current point being filled
	int point_;

	//! An indexed triangle of vertices
	IndexedTrgl trgl_;

	//! Group name
	GEString name_;
	//! The triangle subgroup currently being used
	TrglMeshSubGroup subgroup_;

protected:
	//! Defined but not implemented to forbid the use of this method
	TrglMeshCreator(const TrglMeshCreator& rhs);

	//! Defined but not implemented to forbid the use of this method
	TrglMeshCreator& operator=(const TrglMeshCreator& rhs);
};


#ifdef GAMEENGINE_NAMESPACES
} // namespace GameEngine
#endif

#endif
